#include<stdio.h>
#include<fcntl.h>
#include<linux/input.h>

#include<linux/fb.h>
#include<sys/mman.h>
#include<rk_fb.h>

#include<stdlib.h>
#include"fb.h"

static struct osd_s osd0 = {0, 0, {NULL, NULL}, 0};


int fb_init(void)
{
	struct fb *fb0 = rk_fb_init(FB_FORMAT_BGRA_8888);

	struct fb_var_screeninfo var;
	if (ioctl(fb0->fd, FBIOGET_VSCREENINFO, &var) < 0)
		return -1;

	int share_fd = 0;
	if (ioctl(fb0->fd, 0x5003, &share_fd) != 0)
		return -1;
	
	osd0.w = var.xres;
	osd0.h = var.yres;
	osd0.size = var.yres * var.xres * var.bits_per_pixel / 8;
	osd0.buf[0] = (char *)mmap(NULL, osd0.size, PROT_READ | PROT_WRITE, MAP_SHARED, share_fd, 0);
	osd0.buf[1] = calloc(1, osd0.size);
	if (osd0.buf[1] == NULL) {
		printf("osd0.buf[1] alloc fail!\n");
		return -1;
	}
	return 0;
}

inline int set_point_color(int x, int y, int color) 
{
	unsigned int *dst = NULL;
	dst = (unsigned int *)osd0.buf[1] + osd0.w * osd0.h - (osd0.w * x + y);
	*dst = color;
}

inline void osd_fill_rect(int x, int y, int w, int h, int color)
{
	int i, j;
	for (i = x; i < x + h; i++)
		for (j = y; j < y + w; j++)
			set_point_color(i, j, color);
}

inline void put_point_buf(int x, int y)
{
	unsigned int *dst = NULL;
	dst = (unsigned int *)osd0.buf[0] + osd0.w * osd0.h - (osd0.w * x + y);
	*dst = *((unsigned int *)osd0.buf[1] + osd0.w * osd0.h - (osd0.w * x + y));
}

inline void osd_draw_rect(int x, int y, int w, int h)
{
	int i, j;
	for (i = x; i < x + h; i++)
		for (j = y; j < y + w; j++)
			put_point_buf(i, j);
}

inline void osd_draw_color(int x, int y, int w, int h, int color)
{
	osd_fill_rect(x, y, w, h, color);
	osd_draw_rect(x, y, w, h);
}
